from sqladmin import Admin, ModelView, BaseView, expose
from sqladmin.authentication import AuthenticationBackend
from starlette.requests import Request
from starlette.responses import RedirectResponse, JSONResponse, FileResponse
from fastapi.templating import Jinja2Templates
from fastapi import HTTPException
from sqlalchemy import select
import jwt
import os
from datetime import datetime, timedelta
from typing import List, Dict, Any
from database.models import (
    User, Product, Order, Manufacturer, Model3D, 
    ProductionJob, Category, ProductImage, SystemConfig,
    Model3DUpload, ShopifySyncLog, ProductionStats
)
from database.connection import engine, get_session
from services.report_service import ReportService
import logging
from wtforms import PasswordField
from wtforms.validators import DataRequired, Length

# JWT配置
SECRET_KEY = os.getenv("SECRET_KEY", "your-secret-key-here")
ALGORITHM = "HS256"

logger = logging.getLogger(__name__)

# 用户管理视图
class UserAdmin(ModelView, model=User):
    column_list = [User.id, User.username, User.email, User.role, User.is_active, User.created_at]
    column_searchable_list = [User.username, User.email, User.full_name]
    column_sortable_list = [User.id, User.username, User.created_at]
    
    # 列标签中文显示
    column_labels = {
        User.id: "用户ID",
        User.username: "用户名",
        User.email: "邮箱地址",
        User.full_name: "姓名",
        User.phone: "联系电话",
        User.role: "用户角色",
        User.is_active: "是否激活",
        User.avatar_url: "头像链接",
        User.created_at: "创建时间",
        User.updated_at: "更新时间"
    }
    
    # 表单验证规则
    form_args = {
        "username": {
            "description": "用户名必须唯一，长度3-50个字符"
        },
        "email": {
            "description": "请输入有效的邮箱地址"
        },
        "role": {
            "description": "admin: 管理员, customer: 客户, manufacturer: 厂商"
        },
        "password": {
            "description": "用户密码，至少6个字符"
        }
    }
    
    # 添加虚拟密码字段，仅用于表单显示
    form_extra_fields = {
        "password": PasswordField("密码", validators=[Length(min=6)], default="123456", description="用户密码，至少6个字符")
    }
    
    # 自定义查询
    def get_query(self):
        return self.session.query(User).filter(User.role != "system")
    
    # 用户创建和编辑时的业务逻辑
    async def on_model_change(self, data, model, is_created, request):
        from werkzeug.security import generate_password_hash
        
        if is_created:
            # 新用户创建时设置默认密码
            model.hashed_password = generate_password_hash("123456")
        else:
            # 编辑现有用户时不修改密码
            pass
    
    form_columns = [
        "username", "email", "full_name", "phone", "role", 
        "is_active", "avatar_url"
    ]
    
    name = "用户管理"
    name_plural = "用户管理"
    icon = "fa-solid fa-user"


# 商品分类管理视图
class CategoryAdmin(ModelView, model=Category):
    column_list = [Category.id, Category.name, Category.is_active, Category.sort_order]
    column_searchable_list = [Category.name, Category.description]
    column_sortable_list = [Category.id, Category.sort_order]
    
    form_columns = ["name", "description", "image_url", "sort_order", "is_active"]
    
    name = "商品分类"
    name_plural = "商品分类"
    icon = "fa-solid fa-tags"


# 商品管理视图
class ProductAdmin(ModelView, model=Product):
    column_list = [
        Product.id, Product.name, Product.category_id, Product.price,
        Product.is_active, Product.stock_quantity, Product.created_at
    ]
    column_searchable_list = [Product.name, Product.description]
    column_sortable_list = [Product.id, Product.name, Product.price, Product.created_at]
    
    # 列标签中文显示
    column_labels = {
        Product.id: "商品ID",
        Product.name: "商品名称",
        Product.description: "商品描述",
        Product.price: "价格",
        Product.category_id: "商品分类",
        Product.shopify_product_id: "Shopify产品ID",
        Product.template_3d_url: "3D模板链接",
        Product.default_material: "默认材料",
        Product.available_materials: "可用材料",
        Product.is_active: "是否激活",
        Product.stock_quantity: "库存数量",
        Product.created_at: "创建时间",
        Product.updated_at: "更新时间"
    }
    
    # 表单验证规则
    form_args = {
        "name": {
            "description": "商品名称不能为空"
        },
        "price": {
            "description": "价格必须为正数"
        },
        "category_id": {
            "description": "必须选择商品分类"
        }
    }
    
    # 自定义格式化
    column_formatters = {
        Product.price: lambda m, a: f"¥{m.price:.2f}",
        Product.is_active: lambda m, a: "✅" if m.is_active else "❌"
    }
    
    # 业务逻辑：商品保存时同步到Shopify
    async def on_model_change(self, data, model, is_created, request):
        if model.shopify_product_id:
            # 如果已有Shopify ID，更新商品信息
            print(f"更新Shopify商品: {model.shopify_product_id}")
        return model
    
    form_columns = [
        "name", "description", "price", "category_id", "shopify_product_id",
        "template_3d_url", "default_material", "available_materials",
        "is_active", "stock_quantity"
    ]
    
    name = "商品管理"
    name_plural = "商品管理"
    icon = "fa-solid fa-box"


# 订单管理视图
class OrderAdmin(ModelView, model=Order):
    column_list = [
        Order.id, Order.order_number, Order.user_id, Order.product_id,
        Order.status, Order.total_amount, Order.created_at
    ]
    column_searchable_list = [Order.order_number, Order.shipping_name, Order.shipping_phone]
    column_sortable_list = [Order.id, Order.created_at, Order.total_amount]
    
    form_columns = [
        "order_number", "user_id", "product_id", "model_3d_id",
        "quantity", "unit_price", "total_amount", "status",
        "custom_material", "custom_size", "custom_color",
        "shipping_address", "shipping_name", "shipping_phone"
    ]
    
    name = "订单管理"
    name_plural = "订单管理"
    icon = "fa-solid fa-shopping-cart"
    
    # 自定义删除方法，处理业务逻辑
    async def delete_model(self, request: Request, pk: Any) -> None:
        """自定义删除模型，包含业务逻辑检查"""
        from sqlalchemy.ext.asyncio import AsyncSession
        from database.connection import engine
        from sqlalchemy import select
        
        logger.info(f"🗑️ delete_model called with pk: {pk}")
        logger.info(f"📋 Request method: {request.method}")
        logger.info(f"🌐 Request URL: {request.url}")
        
        session = None
        try:
            # 创建新的数据库会话
            session = AsyncSession(engine)
            
            # 使用新会话获取订单对象，确保在同一个事务中
            from database.models import Order
            result = await session.execute(select(Order).where(Order.id == pk))
            order = result.scalar_one_or_none()
            
            if not order:
                raise HTTPException(status_code=404, detail="订单不存在")
            
            # 检查是否可以删除（仅未支付订单可删除）
            if order.payment_status == "paid":
                raise HTTPException(status_code=400, detail="已支付订单不能删除")
            
            # 恢复库存
            if order.status != "cancelled":
                from database.models import Product
                result = await session.execute(select(Product).where(Product.id == order.product_id))
                product = result.scalar_one_or_none()
                if product:
                    product.stock_quantity += order.quantity
                    session.add(product)
            
            # 删除相关生产任务
            from database.models import ProductionJob
            result = await session.execute(
                select(ProductionJob).where(ProductionJob.order_id == pk)
            )
            production_jobs = result.scalars().all()
            
            # 逐个删除生产任务
            for job in production_jobs:
                await session.delete(job)
            
            # 删除订单
            await session.delete(order)
            await session.commit()
            
            logger.info(f"✅ 订单 {pk} 删除成功")
            
        except HTTPException:
            # 重新抛出HTTP异常
            if session:
                await session.rollback()
            raise
        except Exception as e:
            # 记录错误日志
            logger.error(f"删除订单失败: {str(e)}")
            # 回滚事务
            if session:
                await session.rollback()
            raise HTTPException(status_code=500, detail=f"删除订单失败: {str(e)}")
        finally:
            # 确保会话被关闭
            if session:
                await session.close()
    
    # 尝试覆盖其他可能的删除方法
    def delete(self, pk):
        """尝试覆盖delete方法"""
        logger.info(f"🗑️ delete method called with pk: {pk}")
        return super().delete(pk)
    
    def delete_model_sync(self, pk):
        """尝试覆盖同步删除方法"""
        logger.info(f"🗑️ delete_model_sync called with pk: {pk}")
        return super().delete_model_sync(pk)
    
    async def on_model_delete(self, model):
        """模型删除前的回调"""
        logger.info(f"🗑️ on_model_delete called with model: {model}")
        return await super().on_model_delete(model)


# 3D模型管理视图
class Model3DAdmin(ModelView, model=Model3D):
    column_list = [
        Model3D.id, Model3D.product_id, Model3D.source_image_id,
        Model3D.file_format, Model3D.status, Model3D.is_optimized, 
        Model3D.vertices_count, Model3D.faces_count, Model3D.created_at
    ]
    column_searchable_list = [Model3D.model_file_url, Model3D.ai_model_used, Model3D.original_filename]
    column_sortable_list = [Model3D.id, Model3D.created_at, Model3D.status]
    
    # 列标签中文显示
    column_labels = {
        Model3D.id: "模型ID",
        Model3D.product_id: "商品ID",
        Model3D.source_image_id: "源图片ID",
        Model3D.original_filename: "原始文件名",
        Model3D.storage_path: "存储路径",
        Model3D.model_file_url: "模型文件链接",
        Model3D.preview_image_url: "预览图链接",
        Model3D.file_format: "文件格式",
        Model3D.status: "模型状态",
        Model3D.error_message: "错误信息",
        Model3D.vertices_count: "顶点数",
        Model3D.faces_count: "面数",
        Model3D.dimensions: "尺寸信息",
        Model3D.shopify_asset_id: "Shopify资源ID",
        Model3D.shopify_product_id: "Shopify产品ID",
        Model3D.is_optimized: "是否优化",
        Model3D.optimization_time: "优化时间(秒)",
        Model3D.version: "版本号",
        Model3D.created_at: "创建时间",
        Model3D.generated_at: "生成时间",
        Model3D.optimized_at: "优化时间",
        Model3D.uploaded_at: "上传时间"
    }
    
    # 状态颜色格式化
    column_formatters = {
        Model3D.status: lambda m, a: f"<span class='badge badge-{m.status}'>{m.status}</span>",
        Model3D.is_optimized: lambda m, a: "✅" if m.is_optimized else "❌"
    }
    
    # 表单验证规则
    form_args = {
        "product_id": {
            "description": "必须关联到商品"
        },
        "original_filename": {
            "description": "原始文件名不能为空"
        },
        "storage_path": {
            "description": "存储路径不能为空"
        }
    }
    
    # 自定义查询 - 按状态筛选
    def get_query(self):
        return self.session.query(Model3D).filter(Model3D.status != "deleted")
    
    # 业务逻辑：模型状态变更处理
    async def on_model_change(self, data, model, is_created, request):
        if not is_created:
            # 检查状态变更
            old_model = self.session.query(Model3D).filter(Model3D.id == model.id).first()
            if old_model and old_model.status != model.status:
                print(f"模型状态变更: {old_model.status} -> {model.status}")
                # 可以在这里添加状态变更通知逻辑
        return model
    
    form_columns = [
        "product_id", "source_image_id", "original_filename", "storage_path",
        "model_file_url", "preview_image_url", "file_format", "status",
        "vertices_count", "faces_count", "dimensions", "shopify_asset_id",
        "shopify_product_id", "is_optimized", "parameters", "ai_model_used"
    ]
    
    name = "3D模型管理"
    name_plural = "3D模型管理"
    icon = "fa-solid fa-cube"


# 厂商管理视图
class ManufacturerAdmin(ModelView, model=Manufacturer):
    column_list = [
        Manufacturer.id, Manufacturer.company_name, Manufacturer.contact_person,
        Manufacturer.is_active, Manufacturer.rating
    ]
    column_searchable_list = [Manufacturer.company_name, Manufacturer.contact_person, Manufacturer.email]
    column_sortable_list = [Manufacturer.id, Manufacturer.rating]
    
    form_columns = [
        "company_name", "contact_person", "email", "phone", "address",
        "supported_materials", "max_production_capacity", "production_lead_time",
        "api_endpoint", "is_active", "rating"
    ]
    
    name = "厂商管理"
    name_plural = "厂商管理"
    icon = "fa-solid fa-industry"


# 生产任务管理视图
class ProductionJobAdmin(ModelView, model=ProductionJob):
    column_list = [
        ProductionJob.id, ProductionJob.job_number, ProductionJob.order_id,
        ProductionJob.manufacturer_id, ProductionJob.status, ProductionJob.progress_percentage
    ]
    column_searchable_list = [ProductionJob.job_number, ProductionJob.production_file_url]
    column_sortable_list = [ProductionJob.id, ProductionJob.created_at, ProductionJob.priority]
    
    form_columns = [
        "job_number", "order_id", "manufacturer_id", "production_file_url",
        "file_format", "material_specification", "quantity", "priority",
        "status", "progress_percentage", "production_cost"
    ]
    
    name = "生产任务"
    name_plural = "生产任务"
    icon = "fa-solid fa-cogs"


# 系统配置管理视图
class SystemConfigAdmin(ModelView, model=SystemConfig):
    column_list = [SystemConfig.id, SystemConfig.config_key, SystemConfig.config_value, SystemConfig.config_type]
    column_searchable_list = [SystemConfig.config_key, SystemConfig.description]
    column_sortable_list = [SystemConfig.id, SystemConfig.config_key]
    
    # 列标签中文显示
    column_labels = {
        SystemConfig.id: "配置ID",
        SystemConfig.config_key: "配置键",
        SystemConfig.config_value: "配置值",
        SystemConfig.config_type: "配置类型",
        SystemConfig.description: "配置描述",
        SystemConfig.is_sensitive: "是否敏感",
        SystemConfig.created_at: "创建时间",
        SystemConfig.updated_at: "更新时间"
    }
    
    form_columns = ["config_key", "config_value", "description", "config_type", "is_sensitive"]
    
    name = "系统配置"
    name_plural = "系统配置"
    icon = "fa-solid fa-gear"


# 3D模型上传管理视图
class Model3DUploadAdmin(ModelView, model=Model3DUpload):
    column_list = [
        Model3DUpload.id, Model3DUpload.user_id, Model3DUpload.product_id,
        Model3DUpload.original_filename, Model3DUpload.status, 
        Model3DUpload.shopify_sync_status, Model3DUpload.created_at
    ]
    column_searchable_list = [Model3DUpload.original_filename, Model3DUpload.file_format]
    column_sortable_list = [Model3DUpload.id, Model3DUpload.created_at, Model3DUpload.status]
    
    # 列标签中文显示
    column_labels = {
        Model3DUpload.id: "上传ID",
        Model3DUpload.user_id: "用户ID",
        Model3DUpload.product_id: "商品ID",
        Model3DUpload.original_filename: "原始文件名",
        Model3DUpload.file_url: "文件链接",
        Model3DUpload.file_size: "文件大小",
        Model3DUpload.file_format: "文件格式",
        Model3DUpload.mime_type: "MIME类型",
        Model3DUpload.storage_path: "存储路径",
        Model3DUpload.status: "处理状态",
        Model3DUpload.error_message: "错误信息",
        Model3DUpload.generation_params: "生成参数",
        Model3DUpload.ai_model_preference: "AI模型偏好",
        Model3DUpload.generated_model_id: "生成模型ID",
        Model3DUpload.processing_time: "处理时间(秒)",
        Model3DUpload.shopify_sync_status: "Shopify同步状态",
        Model3DUpload.shopify_product_id: "Shopify产品ID",
        Model3DUpload.shopify_errors: "Shopify错误",
        Model3DUpload.created_at: "创建时间",
        Model3DUpload.updated_at: "更新时间"
    }
    
    # 状态格式化
    column_formatters = {
        Model3DUpload.status: lambda m, a: f"<span class='badge badge-{m.status}'>{m.status}</span>",
        Model3DUpload.file_size: lambda m, a: f"{m.file_size / 1024 / 1024:.2f} MB" if m.file_size else "0 MB"
    }
    
    form_columns = [
        "user_id", "product_id", "original_filename", "file_url", "file_size",
        "file_format", "mime_type", "storage_path", "status", "generation_params",
        "ai_model_preference", "shopify_sync_status", "shopify_product_id"
    ]
    
    name = "3D模型上传"
    name_plural = "3D模型上传"
    icon = "fa-solid fa-upload"


# Shopify同步日志管理视图
class ShopifySyncLogAdmin(ModelView, model=ShopifySyncLog):
    column_list = [
        ShopifySyncLog.id, ShopifySyncLog.model_3d_id, ShopifySyncLog.shopify_resource_type,
        ShopifySyncLog.shopify_operation, ShopifySyncLog.sync_status, ShopifySyncLog.created_at
    ]
    column_searchable_list = [ShopifySyncLog.shopify_resource_id, ShopifySyncLog.error_message]
    column_sortable_list = [ShopifySyncLog.id, ShopifySyncLog.created_at]
    
    # 列标签中文显示
    column_labels = {
        ShopifySyncLog.id: "日志ID",
        ShopifySyncLog.model_3d_id: "3D模型ID",
        ShopifySyncLog.upload_id: "上传ID",
        ShopifySyncLog.order_id: "订单ID",
        ShopifySyncLog.shopify_resource_type: "Shopify资源类型",
        ShopifySyncLog.shopify_resource_id: "Shopify资源ID",
        ShopifySyncLog.shopify_operation: "操作类型",
        ShopifySyncLog.request_data: "请求数据",
        ShopifySyncLog.response_data: "响应数据",
        ShopifySyncLog.sync_status: "同步状态",
        ShopifySyncLog.error_message: "错误信息",
        ShopifySyncLog.response_time: "响应时间(毫秒)",
        ShopifySyncLog.retry_count: "重试次数",
        ShopifySyncLog.created_at: "创建时间",
        ShopifySyncLog.synced_at: "同步时间"
    }
    
    # 状态格式化
    column_formatters = {
        ShopifySyncLog.sync_status: lambda m, a: f"<span class='badge badge-{'success' if m.sync_status == 'success' else 'danger'}'>{m.sync_status}</span>"
    }
    
    form_columns = [
        "model_3d_id", "upload_id", "order_id", "shopify_resource_type",
        "shopify_resource_id", "shopify_operation", "request_data",
        "response_data", "sync_status", "error_message", "response_time", "retry_count"
    ]
    
    name = "Shopify同步日志"
    name_plural = "Shopify同步日志"
    icon = "fa-solid fa-sync"


# 生产统计管理视图
class ProductionStatsAdmin(ModelView, model=ProductionStats):
    column_list = [
        ProductionStats.id, ProductionStats.stat_date, ProductionStats.manufacturer_id,
        ProductionStats.models_generated, ProductionStats.models_optimized,
        ProductionStats.orders_received, ProductionStats.total_revenue
    ]
    column_searchable_list = [ProductionStats.stat_date]
    column_sortable_list = [ProductionStats.id, ProductionStats.stat_date, ProductionStats.total_revenue]
    
    # 列标签中文显示
    column_labels = {
        ProductionStats.id: "统计ID",
        ProductionStats.stat_date: "统计日期",
        ProductionStats.manufacturer_id: "厂商ID",
        ProductionStats.product_id: "商品ID",
        ProductionStats.models_generated: "生成模型数",
        ProductionStats.models_optimized: "优化模型数",
        ProductionStats.models_uploaded: "上传模型数",
        ProductionStats.models_failed: "失败模型数",
        ProductionStats.orders_received: "接收订单数",
        ProductionStats.orders_completed: "完成订单数",
        ProductionStats.orders_failed: "失败订单数",
        ProductionStats.production_jobs: "生产任务数",
        ProductionStats.production_completed: "完成生产数",
        ProductionStats.production_failed: "失败生产数",
        ProductionStats.total_revenue: "总收入",
        ProductionStats.total_cost: "总成本",
        ProductionStats.created_at: "创建时间",
        ProductionStats.updated_at: "更新时间"
    }
    
    # 数值格式化 - 使用2个参数
    column_formatters = {
        ProductionStats.total_revenue: lambda value, obj: f"¥{value:.2f}" if isinstance(value, (int, float)) else str(value),
        ProductionStats.total_cost: lambda value, obj: f"¥{value:.2f}" if isinstance(value, (int, float)) else str(value),
        ProductionStats.stat_date: lambda value, obj: value.strftime("%Y-%m-%d") if hasattr(value, 'strftime') else str(value)
    }
    
    form_columns = [
        "stat_date", "manufacturer_id", "product_id", "models_generated",
        "models_optimized", "models_uploaded", "models_failed", "orders_received",
        "orders_completed", "orders_failed", "production_jobs", "production_completed",
        "production_failed", "total_revenue", "total_cost"
    ]
    
    name = "生产统计"
    name_plural = "生产统计"
    icon = "fa-solid fa-chart-bar"


# 报表仪表板视图
class ReportDashboardView(BaseView):
    """报表仪表板视图"""
    
    name = "数据统计报表"
    icon = "fa-chart-bar"
    
    def __init__(self):
        super().__init__()
        # 初始化Jinja2Templates实例
        self.templates = Jinja2Templates(directory="templates")
    
    @expose("/", methods=["GET"])
    async def index(self, request: Request):
        """报表仪表板首页"""
        try:
            # 获取基本统计数据
            async with get_session() as session:
                report_service = ReportService(session)
                stats = await report_service.get_dashboard_stats()
                
                # 获取订单状态统计
                order_stats = await report_service.get_order_stats_by_status()
                
                # 获取收入统计（最近30天）
                revenue_stats = await report_service.get_revenue_stats(30)
                
                # 获取用户统计
                user_stats = await report_service.get_user_stats()
                
                # 获取生产统计
                production_stats = await report_service.get_production_stats()
                
                # 处理图表数据格式
                revenue_data = {
                    'dates': [item['date'] for item in revenue_stats.get('daily_revenue', [])],
                    'daily_revenue': [item['revenue'] for item in revenue_stats.get('daily_revenue', [])]
                }
                
                order_data = {
                    'labels': list(order_stats.keys()),
                    'values': list(order_stats.values())
                }
                
                user_growth = user_stats.get('growth_trend', [])
                user_data = {
                    'dates': [item['date'] for item in user_growth],
                    'daily_users': [item['new_users'] for item in user_growth]
                }
                
                production_jobs = production_stats.get('jobs_by_status', {})
                production_data = {
                    'pending_jobs': production_jobs.get('pending', 0),
                    'processing_jobs': production_jobs.get('in_progress', 0),
                    'completed_jobs': production_jobs.get('completed', 0),
                    'failed_jobs': production_jobs.get('failed', 0)
                }
                
                # 获取最近订单数据
                recent_orders = await self._get_recent_orders(session)
                stats['recent_orders'] = recent_orders
                
                context = {
                    "stats": stats,
                    "order_stats": order_data,
                    "revenue_stats": revenue_data,
                    "user_stats": user_data,
                    "production_stats": production_data,
                    "request": request
                }
                
                return self.templates.TemplateResponse("reports/dashboard.html", context)
                
        except Exception as e:
            logger.error(f"加载报表仪表板失败: {e}")
            return self.templates.TemplateResponse(
                "error.html", 
                {"message": "加载报表数据失败，请稍后重试", "request": request}
            )
    
    async def _get_recent_orders(self, session) -> List[Dict[str, Any]]:
        """获取最近订单"""
        try:
            from sqlalchemy import select
            from sqlalchemy.orm import selectinload
            
            stmt = select(Order).options(
                selectinload(Order.user),
                selectinload(Order.items).selectinload(OrderItem.product)
            ).order_by(Order.created_at.desc()).limit(10)
            
            result = await session.execute(stmt)
            orders = result.scalars().all()
            
            recent_orders = []
            for order in orders:
                status_map = {
                    'pending': ('待处理', 'warning'),
                    'confirmed': ('已确认', 'info'),
                    'processing': ('处理中', 'primary'),
                    'shipped': ('已发货', 'secondary'),
                    'delivered': ('已送达', 'success'),
                    'cancelled': ('已取消', 'danger')
                }
                status_text, status_color = status_map.get(order.status.value, ('未知', 'secondary'))
                
                product_name = order.items[0].product.name if order.items else '未知商品'
                customer_name = order.user.username if order.user else '未知用户'
                
                recent_orders.append({
                    'order_number': order.order_number,
                    'customer_name': customer_name,
                    'product_name': product_name,
                    'total_amount': float(order.total_amount),
                    'status_text': status_text,
                    'status_color': status_color,
                    'created_at': order.created_at.strftime('%Y-%m-%d %H:%M')
                })
            
            return recent_orders
            
        except Exception as e:
            logger.error(f"获取最近订单失败: {str(e)}")
            return []
    
    @expose("/detailed-reports", methods=["GET"])
    async def detailed_reports(self, request: Request):
        """详细报表页面"""
        try:
            # 获取查询参数
            start_date = request.query_params.get("start_date")
            end_date = request.query_params.get("end_date")
            
            # 处理日期参数
            if start_date:
                start_date = datetime.strptime(start_date, "%Y-%m-%d")
            else:
                start_date = datetime.now() - timedelta(days=30)
            
            if end_date:
                end_date = datetime.strptime(end_date, "%Y-%m-%d")
            else:
                end_date = datetime.now()
            
            async for session in get_session():
                report_service = ReportService(session)
                
                # 获取详细统计数据
                order_stats = await self._get_order_stats(session, start_date, end_date)
                user_stats = await self._get_user_stats(session, start_date, end_date)
                product_stats = await self._get_product_stats(session, start_date, end_date)
                production_stats = await self._get_production_stats(session, start_date, end_date)
                
                stats = {
                    "orders": order_stats,
                    "users": user_stats,
                    "products": product_stats,
                    "production": production_stats
                }
                
                context = {
                    "stats": stats,
                    "start_date": start_date.strftime("%Y-%m-%d"),
                    "end_date": end_date.strftime("%Y-%m-%d"),
                    "request": request
                }
                
                logger.info(f"准备渲染详细报表模板: reports/detailed.html")
                logger.info(f"模板对象类型: {type(self.templates)}")
                return self.templates.TemplateResponse("reports/detailed.html", context)
                
        except Exception as e:
            logger.error(f"加载详细报表失败: {e}")
            return self.templates.TemplateResponse(
                "error.html", 
                {"message": "加载详细报表失败，请稍后重试", "request": request}
            )
    
    async def _get_order_stats(self, session, start_date: datetime, end_date: datetime) -> Dict[str, Any]:
        """获取订单统计"""
        try:
            from sqlalchemy import select, func, and_
            
            # 基础统计
            total_orders = await session.scalar(
                select(func.count(Order.id)).where(
                    and_(Order.created_at >= start_date, Order.created_at <= end_date)
                )
            )
            
            total_revenue = await session.scalar(
                select(func.sum(Order.total_amount)).where(
                    and_(Order.created_at >= start_date, Order.created_at <= end_date)
                )
            ) or 0
            
            avg_revenue = float(total_revenue) / total_orders if total_orders > 0 else 0
            
            # 状态分布
            status_stats = await session.execute(
                select(
                    Order.status,
                    func.count(Order.id).label('count'),
                    func.sum(Order.total_amount).label('revenue')
                ).where(
                    and_(Order.created_at >= start_date, Order.created_at <= end_date)
                ).group_by(Order.status)
            )
            
            status_breakdown = []
            status_map = {
                'pending': ('待处理', 'warning'),
                'confirmed': ('已确认', 'info'),
                'processing': ('处理中', 'primary'),
                'shipped': ('已发货', 'secondary'),
                'delivered': ('已送达', 'success'),
                'cancelled': ('已取消', 'danger')
            }
            
            for status, count, revenue in status_stats:
                name, color = status_map.get(status.value, ('未知', 'secondary'))
                percentage = (count / total_orders * 100) if total_orders > 0 else 0
                avg_amount = float(revenue) / count if count > 0 else 0
                
                status_breakdown.append({
                    'name': name,
                    'color': color,
                    'count': count,
                    'percentage': percentage,
                    'revenue': float(revenue),
                    'avg_amount': avg_amount
                })
            
            # 完成率
            completed_orders = await session.scalar(
                select(func.count(Order.id)).where(
                    and_(
                        Order.created_at >= start_date,
                        Order.created_at <= end_date,
                        Order.status == 'delivered'
                    )
                )
            )
            
            completion_rate = (completed_orders / total_orders * 100) if total_orders > 0 else 0
            
            return {
                'total': total_orders,
                'total_revenue': float(total_revenue),
                'avg_revenue': avg_revenue,
                'completion_rate': completion_rate,
                'status_breakdown': status_breakdown
            }
            
        except Exception as e:
            logger.error(f"获取订单统计失败: {str(e)}")
            return {
                'total': 0,
                'total_revenue': 0,
                'avg_revenue': 0,
                'completion_rate': 0,
                'status_breakdown': []
            }
    
    async def _get_user_stats(self, session, start_date: datetime, end_date: datetime) -> Dict[str, Any]:
        """获取用户统计"""
        try:
            from sqlalchemy import select, func, and_
            
            # 基础统计
            total_users = await session.scalar(select(func.count(User.id)))
            active_users = await session.scalar(
                select(func.count(User.id)).where(User.last_login >= start_date)
            )
            
            # 新增用户趋势
            daily_users_result = await session.execute(
                select(
                    func.date(User.created_at).label('date'),
                    func.count(User.id).label('count')
                ).where(
                    and_(User.created_at >= start_date, User.created_at <= end_date)
                ).group_by(func.date(User.created_at)).order_by('date')
            )
            
            dates = []
            daily_counts = []
            for row in daily_users_result:
                dates.append(row.date.strftime('%Y-%m-%d'))
                daily_counts.append(row.count)
            
            # 月增长率
            last_month_start = datetime.now() - timedelta(days=60)
            last_month_end = datetime.now() - timedelta(days=30)
            
            last_month_users = await session.scalar(
                select(func.count(User.id)).where(
                    and_(User.created_at >= last_month_start, User.created_at < last_month_end)
                )
            )
            
            this_month_users = await session.scalar(
                select(func.count(User.id)).where(User.created_at >= start_date)
            )
            
            growth_rate = ((this_month_users - last_month_users) / last_month_users * 100) if last_month_users > 0 else 0
            
            # 用户类型分布
            user_orders_result = await session.execute(
                select(
                    User.id,
                    func.count(Order.id).label('order_count'),
                    func.sum(Order.total_amount).label('total_spent')
                ).outerjoin(Order).group_by(User.id)
            )
            
            new_users = 0
            regular_users = 0
            vip_users = 0
            total_orders = 0
            
            for row in user_orders_result:
                if row.order_count == 0:
                    new_users += 1
                elif row.order_count <= 5:
                    regular_users += 1
                else:
                    vip_users += 1
                total_orders += row.order_count
            
            avg_orders = total_orders / total_users if total_users > 0 else 0
            
            type_breakdown = [
                {
                    'name': '新用户',
                    'count': new_users,
                    'percentage': (new_users / total_users * 100) if total_users > 0 else 0,
                    'orders': 0,
                    'avg_order_amount': 0
                },
                {
                    'name': '普通用户',
                    'count': regular_users,
                    'percentage': (regular_users / total_users * 100) if total_users > 0 else 0,
                    'orders': sum(row.order_count for row in user_orders_result if 1 <= row.order_count <= 5),
                    'avg_order_amount': 0
                },
                {
                    'name': 'VIP用户',
                    'count': vip_users,
                    'percentage': (vip_users / total_users * 100) if total_users > 0 else 0,
                    'orders': sum(row.order_count for row in user_orders_result if row.order_count > 5),
                    'avg_order_amount': 0
                }
            ]
            
            return {
                'total': total_users,
                'active': active_users,
                'growth_rate': growth_rate,
                'avg_orders': round(avg_orders, 1),
                'dates': dates,
                'daily_users': daily_counts,
                'type_breakdown': type_breakdown
            }
            
        except Exception as e:
            logger.error(f"获取用户统计失败: {str(e)}")
            return {
                'total': 0,
                'active': 0,
                'growth_rate': 0,
                'avg_orders': 0,
                'dates': [],
                'daily_users': [],
                'type_breakdown': []
            }
    
    async def _get_product_stats(self, session, start_date: datetime, end_date: datetime) -> Dict[str, Any]:
        """获取商品统计"""
        try:
            from sqlalchemy import select, func, and_
            
            # 基础统计
            total_products = await session.scalar(select(func.count(Product.id)))
            active_products = await session.scalar(
                select(func.count(Product.id)).where(Product.is_active == True)
            )
            
            # 平均价格
            avg_price = await session.scalar(
                select(func.avg(Product.price)).where(Product.is_active == True)
            ) or 0
            
            # 热销商品
            top_selling_result = await session.execute(
                select(
                    Product,
                    func.sum(OrderItem.quantity).label('total_sales'),
                    func.sum(OrderItem.price * OrderItem.quantity).label('total_revenue')
                ).join(OrderItem).join(Order).where(
                    and_(
                        Order.created_at >= start_date,
                        Order.created_at <= end_date,
                        Order.status.in_(['confirmed', 'processing', 'shipped', 'delivered'])
                    )
                ).group_by(Product.id).order_by(func.sum(OrderItem.quantity).desc()).limit(10)
            )
            
            top_selling_data = []
            for product, sales, revenue in top_selling_result:
                top_selling_data.append({
                    'name': product.name,
                    'category': product.category.name if product.category else '未分类',
                    'price': float(product.price),
                    'sales': int(sales),
                    'revenue': float(revenue),
                    'is_active': product.is_active
                })
            
            return {
                'total': total_products,
                'active': active_products,
                'avg_price': float(avg_price),
                'total_sales': sum(item['sales'] for item in top_selling_data),
                'top_selling': top_selling_data
            }
            
        except Exception as e:
            logger.error(f"获取商品统计失败: {str(e)}")
            return {
                'total': 0,
                'active': 0,
                'avg_price': 0,
                'total_sales': 0,
                'top_selling': []
            }
    
    async def _get_production_stats(self, session, start_date: datetime, end_date: datetime) -> Dict[str, Any]:
        """获取生产统计"""
        try:
            from sqlalchemy import select, func, and_
            
            # 基础统计
            total_jobs = await session.scalar(
                select(func.count(ProductionJob.id)).where(
                    and_(ProductionJob.created_at >= start_date, ProductionJob.created_at <= end_date)
                )
            )
            
            completed_jobs = await session.scalar(
                select(func.count(ProductionJob.id)).where(
                    and_(
                        ProductionJob.created_at >= start_date,
                        ProductionJob.created_at <= end_date,
                        ProductionJob.status == 'completed'
                    )
                )
            )
            
            pending_jobs = await session.scalar(
                select(func.count(ProductionJob.id)).where(
                    and_(
                        ProductionJob.created_at >= start_date,
                        ProductionJob.created_at <= end_date,
                        ProductionJob.status == 'pending'
                    )
                )
            )
            
            processing_jobs = await session.scalar(
                select(func.count(ProductionJob.id)).where(
                    and_(
                        ProductionJob.created_at >= start_date,
                        ProductionJob.created_at <= end_date,
                        ProductionJob.status == 'in_progress'
                    )
                )
            )
            
            failed_jobs = await session.scalar(
                select(func.count(ProductionJob.id)).where(
                    and_(
                        ProductionJob.created_at >= start_date,
                        ProductionJob.created_at <= end_date,
                        ProductionJob.status == 'failed'
                    )
                )
            )
            
            # 成功率
            success_rate = (completed_jobs / total_jobs * 100) if total_jobs > 0 else 0
            
            # 平均处理时间
            completed_tasks_result = await session.execute(
                select(ProductionJob).where(
                    and_(
                        ProductionJob.created_at >= start_date,
                        ProductionJob.created_at <= end_date,
                        ProductionJob.status == 'completed',
                        ProductionJob.completed_at.is_not(None)
                    )
                )
            )
            
            completed_tasks = completed_tasks_result.scalars().all()
            total_time = 0
            for task in completed_tasks:
                if task.completed_at and task.created_at:
                    total_time += (task.completed_at - task.created_at).total_seconds() / 3600
            
            avg_time = total_time / len(completed_tasks) if completed_tasks else 0
            
            # 状态分布
            status_breakdown = [
                {
                    'name': '待处理',
                    'color': 'warning',
                    'count': pending_jobs,
                    'percentage': (pending_jobs / total_jobs * 100) if total_jobs > 0 else 0,
                    'avg_time': 0,
                    'description': '等待开始生产'
                },
                {
                    'name': '处理中',
                    'color': 'primary',
                    'count': processing_jobs,
                    'percentage': (processing_jobs / total_jobs * 100) if total_jobs > 0 else 0,
                    'avg_time': 0,
                    'description': '正在生产中'
                },
                {
                    'name': '已完成',
                    'color': 'success',
                    'count': completed_jobs,
                    'percentage': (completed_jobs / total_jobs * 100) if total_jobs > 0 else 0,
                    'avg_time': avg_time,
                    'description': '生产完成'
                },
                {
                    'name': '失败',
                    'color': 'danger',
                    'count': failed_jobs,
                    'percentage': (failed_jobs / total_jobs * 100) if total_jobs > 0 else 0,
                    'avg_time': 0,
                    'description': '生产失败'
                }
            ]
            
            return {
                'total_jobs': total_jobs,
                'completed_jobs': completed_jobs,
                'pending_jobs': pending_jobs,
                'processing_jobs': processing_jobs,
                'failed_jobs': failed_jobs,
                'success_rate': success_rate,
                'avg_time': avg_time,
                'status_breakdown': status_breakdown
            }
            
        except Exception as e:
            logger.error(f"获取生产统计失败: {str(e)}")
            return {
                'total_jobs': 0,
                'completed_jobs': 0,
                'pending_jobs': 0,
                'processing_jobs': 0,
                'failed_jobs': 0,
                'success_rate': 0,
                'avg_time': 0,
                'status_breakdown': []
            }
    
    @expose("/export", methods=["GET"])
    async def export_reports(self, request: Request):
        """报表导出页面"""
        try:
            # 获取查询参数
            export_type = request.query_params.get("export", "all")
            start_date = request.query_params.get("start_date")
            end_date = request.query_params.get("end_date")
            
            # 处理日期参数
            if start_date:
                start_date = datetime.strptime(start_date, "%Y-%m-%d")
            else:
                start_date = datetime.now() - timedelta(days=30)
            
            if end_date:
                end_date = datetime.strptime(end_date, "%Y-%m-%d")
            else:
                end_date = datetime.now()
            
            async for session in get_session():
                report_service = ReportService(session)
                
                # 生成报表文件
                file_path = await report_service.export_report(export_type, "xlsx", start_date, end_date)
                
                if file_path:
                    # 处理文件路径 - ReportService返回的是/uploads/reports/路径
                    if file_path.startswith('/uploads/reports/'):
                        # 从uploads/reports目录复制到exports目录
                        filename = os.path.basename(file_path)
                        source_path = os.path.join('uploads', 'reports', filename)
                        dest_path = os.path.join('exports', filename)
                        
                        # 确保exports目录存在
                        os.makedirs('exports', exist_ok=True)
                        
                        if os.path.exists(source_path):
                            import shutil
                            shutil.copy2(source_path, dest_path)
                            
                            # 返回文件下载URL
                            return JSONResponse({
                                "download_url": f"/admin/export/download/{filename}",
                                "message": "报表生成成功"
                            })
                        else:
                            logger.error(f"源文件不存在: {source_path}")
                            return JSONResponse(
                                {"error": "报表生成失败"},
                                status_code=500
                            )
                    else:
                        # 如果返回的是完整路径
                        if os.path.exists(file_path):
                            filename = os.path.basename(file_path)
                            return JSONResponse({
                                "download_url": f"/admin/export/download/{filename}",
                                "message": "报表生成成功"
                            })
                        else:
                            return JSONResponse(
                                {"error": "报表生成失败"},
                                status_code=500
                            )
                else:
                    return JSONResponse(
                        {"error": "报表生成失败"},
                        status_code=500
                    )
                    
        except Exception as e:
            logger.error(f"导出报表失败: {str(e)}")
            return JSONResponse(
                {"error": f"导出报表失败: {str(e)}"},
                status_code=500
            )
    
    @expose("/export/download/{filename:str}", methods=["GET"])
    async def download_report(self, request: Request):
        """下载报表文件"""
        try:
            filename = request.path_params.get("filename")
            if not filename:
                return JSONResponse({"error": "文件名不能为空"}, status_code=400)
            
            file_path = os.path.join("exports", filename)
            if os.path.exists(file_path):
                return FileResponse(
                    file_path,
                    media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                    filename=filename
                )
            else:
                return JSONResponse({"error": "文件不存在"}, status_code=404)
                
        except Exception as e:
            logger.error(f"下载报表失败: {str(e)}")
            return JSONResponse({"error": f"下载报表失败: {str(e)}"}, status_code=500)


# 新的仪表板视图
class DashboardView(BaseView):
    """美观的仪表板视图"""
    
    name = "数据概览"
    icon = "fa-tachometer-alt"
    
    def __init__(self):
        super().__init__()
        self.templates = Jinja2Templates(directory="templates")
    
    def is_visible(self, request) -> bool:
        """隐藏此视图在导航菜单中的显示"""
        return False
    
    @expose("/dashboard", methods=["GET"])
    async def dashboard(self, request: Request):
        """仪表板首页"""
        try:
            async for session in get_session():
                report_service = ReportService(session)
                
                # 获取基础统计数据
                stats = await report_service.get_dashboard_stats()
                
                # 获取今日新增数据
                from datetime import datetime, timedelta
                today = datetime.now().date()
                yesterday = today - timedelta(days=1)
                
                # 获取今日新用户
                from sqlalchemy import select, func, and_
                from database.models import User, Product, Order, ProductionJob
                
                new_users_today = await session.scalar(
                    select(func.count(User.id)).where(
                        and_(
                            User.created_at >= today,
                            User.created_at < today + timedelta(days=1)
                        )
                    )
                )
                
                new_products_today = await session.scalar(
                    select(func.count(Product.id)).where(
                        and_(
                            Product.created_at >= today,
                            Product.created_at < today + timedelta(days=1)
                        )
                    )
                )
                
                new_orders_today = await session.scalar(
                    select(func.count(Order.id)).where(
                        and_(
                            Order.created_at >= today,
                            Order.created_at < today + timedelta(days=1)
                        )
                    )
                )
                
                production_completed_today = await session.scalar(
                    select(func.count(ProductionJob.id)).where(
                        and_(
                            ProductionJob.updated_at >= today,
                            ProductionJob.status == "completed"
                        )
                    )
                )
                
                # 获取今日收入
                revenue_today = await session.scalar(
                    select(func.sum(Order.total_amount)).where(
                        and_(
                            Order.created_at >= today,
                            Order.created_at < today + timedelta(days=1),
                            Order.status == "delivered"
                        )
                    )
                ) or 0
                
                # 获取最近活动数据
                recent_order = await session.execute(
                    select(Order).order_by(Order.created_at.desc()).limit(1)
                )
                recent_order = recent_order.scalar_one_or_none()
                
                recent_user = await session.execute(
                    select(User).order_by(User.created_at.desc()).limit(1)
                )
                recent_user = recent_user.scalar_one_or_none()
                
                recent_product = await session.execute(
                    select(Product).order_by(Product.created_at.desc()).limit(1)
                )
                recent_product = recent_product.scalar_one_or_none()
                
                # 构建增强的统计数据
                enhanced_stats = {
                    "total_users": stats.get("total_users", 0),
                    "total_products": stats.get("total_products", 0),
                    "total_orders": stats.get("total_orders", 0),
                    "total_revenue": stats.get("total_revenue", 0),
                    "total_production_tasks": stats.get("total_production_tasks", 0),
                    "new_users_today": new_users_today or 0,
                    "new_products_today": new_products_today or 0,
                    "new_orders_today": new_orders_today or 0,
                    "production_completed_today": production_completed_today or 0,
                    "revenue_today": revenue_today,
                    "recent_order_id": recent_order.order_number if recent_order else "N/A",
                    "recent_order_time": recent_order.created_at.strftime("%Y-%m-%d %H:%M") if recent_order else "N/A",
                    "recent_user_name": recent_user.username if recent_user else "N/A",
                    "recent_user_time": recent_user.created_at.strftime("%Y-%m-%d %H:%M") if recent_user else "N/A",
                    "recent_product_name": recent_product.name if recent_product else "N/A",
                    "recent_product_time": recent_product.created_at.strftime("%Y-%m-%d %H:%M") if recent_product else "N/A",
                }
                
                context = {
                    "stats": enhanced_stats,
                    "request": request
                }
                
                return self.templates.TemplateResponse("reports/dashboard.html", context)
                
        except Exception as e:
            logger.error(f"加载仪表板失败: {str(e)}")
            return self.templates.TemplateResponse(
                "error.html",
                {"message": "加载仪表板数据失败，请稍后重试", "request": request}
            )


# 导出报表独立页面视图
class ExportReportsView(BaseView):
    """导出报表独立页面"""
    
    name = "导出报表"
    icon = "fa-download"
    
    def __init__(self):
        super().__init__()
        self.templates = Jinja2Templates(directory="templates")
    
    def is_visible(self, request) -> bool:
        """隐藏此视图在导航菜单中的显示"""
        return False
    
    @expose("/export-reports", methods=["GET"])
    async def export_reports_page(self, request: Request):
        """导出报表页面"""
        try:
            context = {
                "request": request,
                "export_types": [
                    {"key": "all", "name": "完整报表", "description": "包含所有数据的综合报表"},
                    {"key": "orders", "name": "订单报表", "description": "订单统计和明细数据"},
                    {"key": "users", "name": "用户报表", "description": "用户注册和活动数据"},
                    {"key": "products", "name": "商品报表", "description": "商品库存和销售数据"},
                    {"key": "revenue", "name": "收入报表", "description": "收入统计和趋势分析"},
                    {"key": "production", "name": "生产报表", "description": "生产任务和进度数据"}
                ]
            }
            
            return self.templates.TemplateResponse("reports/export.html", context)
            
        except Exception as e:
            logger.error(f"加载导出报表页面失败: {str(e)}")
            return self.templates.TemplateResponse(
                "error.html",
                {"message": "加载导出报表页面失败，请稍后重试", "request": request}
            )


# 管理员认证后端
class AdminAuth(AuthenticationBackend):
    """管理员认证后端"""
    
    async def login(self, request: Request) -> bool:
        form = await request.form()
        username = form.get("username")
        password = form.get("password")
        
        # 简单的管理员认证（实际项目中应该查询数据库）
        if username == "admin" and password == "admin123":
            # 创建JWT token
            token = jwt.encode(
                {
                    "sub": username,
                    "exp": datetime.utcnow() + timedelta(hours=24)
                },
                SECRET_KEY,
                algorithm=ALGORITHM
            )
            request.session.update({"token": token})
            return True
        return False
    
    async def logout(self, request: Request) -> bool:
        request.session.clear()
        return True
    
    async def authenticate(self, request: Request) -> bool:
        token = request.session.get("token")
        
        if not token:
            return False
            
        try:
            payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
            username = payload.get("sub")
            if username == "admin":
                return True
        except jwt.PyJWTError:
            pass
        
        return False


def create_admin(app):
    """创建管理员界面"""
    authentication_backend = AdminAuth(secret_key=SECRET_KEY)
    
    admin = Admin(
        app, 
        engine,
        authentication_backend=authentication_backend,
        title="3D定制商品生产平台 - 后台管理系统",
        base_url="/admin",
        templates_dir="admin/templates"
    )
    
    # 注册基础管理视图
    admin.add_view(UserAdmin)
    admin.add_view(CategoryAdmin)
    admin.add_view(ProductAdmin)
    admin.add_view(OrderAdmin)
    
    # 注册3D模型相关管理视图
    admin.add_view(Model3DAdmin)
    admin.add_view(Model3DUploadAdmin)
    
    # 注册生产相关管理视图
    admin.add_view(ManufacturerAdmin)
    admin.add_view(ProductionJobAdmin)
    admin.add_view(ProductionStatsAdmin)
    
    # 注册系统集成管理视图
    admin.add_view(ShopifySyncLogAdmin)
    admin.add_view(SystemConfigAdmin)
    
    # 添加自定义报表页面
    admin.add_base_view(ReportDashboardView)
    
    # 添加新的美观仪表板
    admin.add_base_view(DashboardView)
    
    # 添加导出报表独立页面
    admin.add_base_view(ExportReportsView)
    
    return admin